home *** CD-ROM | disk | FTP | other *** search
- #include <time.h>
- #include <ctype.h>
- #include <WTime.h>
- #include <WDOS.h>
- #include <WBits.h>
- #pragma hdrstop
-
- // copyright (c) 1993 by Paul Wheaton
-
- extern int DOM[12];//={31,28,31,30,31,30,31,31,30,31,30,31};
-
- //.parse
-
- /*
-
- Converting Julian to Gregorian dates and back. According to the Gregorian
- Calendar Principle:
-
- Each year has 365 days in it
- EXCEPT years that are evenly divisible by 4 (366 days)
- EXCEPT years that are evenly divisible by 100 (365 days)
- EXCEPT years that are evenly divisible by 400 (366 days)
-
- Most four year chunks (a quad) are 1461 days.
- Most 100 year chunks (a century) are 36,524 days.
- All 400 year chunks (quad century) are 116,877 days.
- In theory, the first year (Year 0000) was a leap year.
-
- If you wanted to, you could assume that there are 365.2425 days in the
- average year. If you do try this, remember that floating point math can
- throw you a little bit of round off error - add 0.0000000001 to everything.
-
- I prefer to use integer math since I feel I have more control and more speed.
-
- The way I calculate it, all Quads will have four years where the first year
- is 366 days and each one after that is 365 days. EXCEPT for a Quad that is the
- first Quad in a Century
-
- */
-
- Bool LeapYear(int Year)
- {
- if ((Year%400)==0) return True;
- if ((Year%100)==0) return False;
- if ((Year%4)==0) return True;
- return False;
- }
-
- static const long Q=1461L; // number of days in four years (quad)
- static const long C=36524L; // century
- static const long QC=146097L; // four centuries.
- int DOM[12]={31,28,31,30,31,30,31,31,30,31,30,31};
- // days of the month
-
- static void ConvertJulianToGregorian(long J, int& Y, int& M, int& D)
- {
- long NumQC=J/QC;
- Y=int(NumQC)*400;
- J-=(QC*NumQC);
- long NumC=0;
- if (J>(C+1))
- {
- J-=(C+1);
- Y+=100;
- NumC=J/C;
- Y+=int(NumC)*100;
- J-=NumC*C;
- NumC++;
- }
- if ((NumC>0)&&(J>(Q-1)))
- {
- J-=(Q-1);
- Y+=4;
- }
- long NumQ=J/Q;
- Y+=int(NumQ)*4;
- J-=NumQ*Q;
- int Jul=int(J); // no more need for long int math
- if (LeapYear(Y))
- {
- if (Jul>=366)
- {
- Jul-=366;
- Y++;
- }
- else if (Jul==59) // Jan 1, would have Jul = 0, Feb 29 would have Jul=59
- {
- M=2;
- D=29;
- return;
- }
- else if (Jul>59) Jul--;
- }
- while (Jul>=365)
- {
- Jul-=365;
- Y++;
- }
- M=0;
- while(DOM[M]<=Jul)
- {
- Jul-=DOM[M];
- M++;
- }
- M++;
- D=Jul+1;
- }
-
- static long ConvertGregorianToJulian(int Y, int M, int D)
- {
- Bool Leap=LeapYear(Y-(Y%4));
- int NumQC=Y/400;
- Y-=NumQC*400;
- long J=NumQC*QC;
- int NumC=Y/100;
- if (NumC>0)
- {
- Y-=NumC*100;
- J+=(NumC*C)+1; // the first century has one more day
- }
- int NumQ=Y/4;
- Y-=NumQ*4;
- if ((NumC!=0)&&(NumQ>0))
- {
- // generally, the first Q doesn't have a leap year
- J+=1460;
- NumQ--;
- }
- J+=NumQ*Q;
- if (Leap)
- {
- if (Y>0)
- {
- J+=366;
- Y--;
- }
- else if (M>2) J++;
- }
- while (Y>0)
- {
- J+=365;
- Y--;
- }
- int I;
- For(I,M-1) J+=DOM[I];
- J+=(D-1);
- return J;
- }
-
- Date::Date(const JulianDate& J)
- {
- ConvertJulianToGregorian(J.J,Y,M,D);
- }
-
- void Date::operator=(const JulianDate& J)
- {
- ConvertJulianToGregorian(J.J,Y,M,D);
- }
-
- Bool Date::operator==(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J==X.J);
- }
-
- Bool Date::operator<=(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J<=X.J);
- }
-
- Bool Date::operator>=(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J>=X.J);
- }
-
- Bool Date::operator!=(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J!=X.J);
- }
-
- Bool Date::operator<(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J<=X.J);
- }
-
- Bool Date::operator>(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- return (J>=X.J);
- }
-
- JulianDate Date::operator+(long Days) const
- {
- JulianDate J(ConvertGregorianToJulian(Y,M,D)+Days);
- return J;
- }
-
- JulianDate Date::operator-(long Days) const
- {
- JulianDate J(ConvertGregorianToJulian(Y,M,D)-Days);
- return J;
- }
-
- long Date::operator-(const JulianDate& X) const
- {
- long J=ConvertGregorianToJulian(Y,M,D);
- J-=X.J;
- return J;
- }
-
- JulianDate Date::operator++(int)
- {
- JulianDate J(*this);
- ConvertJulianToGregorian(J.J+1,Y,M,D);
- return J; // return the original value since this is a post inc
- }
-
- JulianDate Date::operator--(int)
- {
- JulianDate J(*this);
- ConvertJulianToGregorian(J.J-1,Y,M,D);
- return J; // return the original value since this is a post dec
- }
-
- JulianDate Date::operator++()
- {
- JulianDate J(*this);
- J.J++;
- ConvertJulianToGregorian(J.J,Y,M,D);
- return J; // return the original value since this is a post inc
- }
-
- JulianDate Date::operator--()
- {
- JulianDate J(*this);
- J.J--;
- ConvertJulianToGregorian(J.J,Y,M,D);
- return J; // return the original value since this is a post dec
- }
-
- void Date::operator+=(long Days)
- {
- JulianDate J(*this);
- J+=Days;
- ConvertJulianToGregorian(J.J,Y,M,D);
- }
-
- void Date::operator-=(long Days)
- {
- JulianDate J(*this);
- J-=Days;
- ConvertJulianToGregorian(J.J,Y,M,D);
- }
-
- //////////////////// Julian stuff
-
- JulianDate::JulianDate(int Year, int Month, int Day)
- {
- J=ConvertGregorianToJulian(Year,Month,Day);
- }
-
- JulianDate::JulianDate(const Date& D)
- {
- J=ConvertGregorianToJulian(D.Y,D.M,D.D);
- }
-
- int JulianDate::Year() const
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- return Y;
- }
-
- int JulianDate::Month() const
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- return M;
- }
-
- int JulianDate::Day() const
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- return D;
- }
-
- void JulianDate::SetYear(int Year)
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- Y=Year;
- J=ConvertGregorianToJulian(Y,M,D);
- }
-
- void JulianDate::SetMonth(int Month)
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- M=Month;
- J=ConvertGregorianToJulian(Y,M,D);
- }
-
- void JulianDate::SetDay(int Day)
- {
- int Y,M,D;
- ConvertJulianToGregorian(J,Y,M,D);
- D=Day;
- J=ConvertGregorianToJulian(Y,M,D);
- }
-
- void JulianDate::operator=(const Date& D)
- {
- J=ConvertGregorianToJulian(D.Y,D.M,D.D);
- }
-
- //.parse
-
- String40 Date::DayStr() const
- {
- char* X="00";
- X[0]=D/10+'0';
- X[1]=D%10+'0';
- return String40(X);
- }
-
- //.parse
-
- String40 Date::MonthStr2() const
- {
- char* X="00";
- X[0]=M/10+'0';
- X[1]=M%10+'0';
- return String40(X);
- }
-
- //.parse
-
- Date::Date(const char* Text)
- {
- String40 S=Text;
- /* possible cases:
- to Today
- tom Tomorrow
- y Yesterday
- m tu w th f sa su (last) Mon, Tue, Wed, Thu, Fri, Sat, Sun
-
- -30 (30 days ago)
- +30 (30 days from now)
-
- 01011993
- 010193
- 0101
- 1-1-1993
- 1-1-93
- 1-1
- 1/1/1993
- 1/1/93
- 1/1
- */
- S.Trim();
- Y=0;
- M=1;
- D=1;
- Date TD=Today();
- JulianDate TDJ(TD);
- int Pos;
- while((Pos=S.Index('/'))!=NotFound) S[Pos]='-';
- if (isdigit(S(0)))
- {
- if (S!="0")
- {
- if (!S.Find('-'))
- {
- if ((S.Length()==8)||(S.Length()==6))
- {
- S.Insert('-',4);
- S.Insert('-',2);
- }
- else if (S.Length()==4) S.Insert('-',2);
- else S="";
- }
- if (S.Length()>2)
- {
- int Pos=S.Index('-');
- M=atoi(S.Before(Pos));
- if (M<1) M=1;
- else if (M>12) M=12;
- S=S.After(Pos);
- Pos=S.Index('-');
- if (Pos==NotFound)
- {
- D=atoi(S);
- if (D<1) D=1;
- else if (D>31) D=31;
- Y=TD.Year();
- if ((*this)>TDJ) Y--;
- }
- else
- {
- D=atoi(S.Before(Pos));
- if (D<1) D=1;
- else if (D>31) D=31;
- Y=atoi(S.After(Pos));
- if (Y<100) Y+=1900;
- }
- if ((Y!=0)&&(D>28))
- {
- if (M==2)
- {
- if (LeapYear(Y)) D=29;
- else D=28;
- }
- else if (D>DOM[M-1]) D=DOM[M-1];
- }
- }
- }
- }
- else
- {
- if (S(0)=='-') (*this)=TDJ-(atoi(S.After(0)));
- else if (S(0)=='+') (*this)=TDJ+(atoi(S.After(0)));
- else
- {
- S.ToLower();
- if (S.Before(3)=="tom") (*this)=TDJ+1;
- else if (S.Before(2)=="to") (*this)=TDJ;
- else if (S(0)=='y') (*this)=TDJ-1;
- else
- {
- int WD=7;
- if (S(0)=='m') WD=0;
- else if (S(0)=='w') WD=2;
- else if (S(0)=='f') WD=4;
- else if (S(0)=='t')
- {
- if (S(1)=='u') WD=1;
- else if (S(1)=='h') WD=3;
- }
- else if (S(0)=='s')
- {
- if (S(1)=='a') WD=5;
- else if (S(1)=='u') WD=6;
- }
- if (WD<7)
- {
- while(TDJ.DOW()!=WD) TDJ--;
- (*this)=TDJ;
- }
- }
- }
- }
- }
-
- //.parse
-
- const char* MonthName[13]=
- {"","January","February","March","April","May","June","July","August",
- "September","October","November","December"};
- const char* WeekdayName[7]=
- {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
-
- String40 Date::MonthStr() const
- {
- String40 MS=MonthName[M];
- return MS;
- }
-
- String40 Date::DayName() const
- {
- String40 DN=WeekdayName[DOW()];
- return DN;
- }
-
- String40 JulianDate::DayName() const
- {
- String40 DN=WeekdayName[DOW()];
- return DN;
- }
-
- //.parse
-
- int Date::DOW() const
- {
- return (JulianDate(*this).DOW());
- }
-
- //.parse
-
- String40 Date::FullDesc() const
- {
- String40 S;
- if (Y!=0) S=DayName()+", "+MonthStr()+' '+Str(D)+", "+Str(Y);
- return S;
- }
-
- //.parse
-
- String40 Date::ShortDesc() const
- {
- String40 S;
- if (Y!=0) S=MonthStr2()+'-'+DayStr()+"-"+Str(Y);
- return S;
- }
-
- //.parse
-
- String40 Date::RelativePastStr() const
- {
- String40 S;
- if (Y!=0)
- {
- JulianDate TJ(Today());
- JulianDate J(*this);
- if (J==TJ) S="Today";
- else if (TJ-J==1) S="Yesterday";
- else if (InRange(TJ-J,0L,6L)) S=J.DayName(); // "Monday", "Tuesday"...
- else S=MonthStr()+' '+Str(D)+", "+Str(Y);
- }
- return S;
- }
-
- //.parse
-
- String40 JulianDate::RelativePastStr(Bool Alpha) const
- {
- String40 S;
- if (J!=0)
- {
- JulianDate TJ(Today());
- if (TJ==J) S="Today";
- else if (TJ-J==1) S="Yesterday";
- else if (InRange((TJ-J).Val(),0L,6L)) S=DayName(); // "Monday", "Tuesday"...
- else
- {
- Date D(*this);
- if (Alpha) S=D.MonthStr()+' '+Str(D.Day())+", "+Str(D.Year());
- else S=D.ShortDesc();
- }
- }
- return S;
- }
-
- //.parse
-
- static BitSet16 Month31;
- static Bool Month31Set=False;
-
- Bool Date::Valid() const
- {
- if (!Month31Set) Month31=BitSet16(1,3,5,7,8,10,12);
- if (Y>4000) return False;
- if (Y<0) return False;
- if (M<1) return False;
- if (M>12) return False;
- if (D<1) return False;
- if (D>31) return False;
- if (Month31(M)) return True;
- if (D>30) return False;
- if (M!=2) return True;
- if (D<29) return True;
- if (LeapYear(Y)) return True;
- return False;
- }
-
- //.parse
-
- JulianDate JulianDate::operator+(long Days) const
- {
- JulianDate JJ=*this;
- JJ.J+=Days;
- return JJ;
- }
-
- JulianDate JulianDate::operator-(long Days) const
- {
- JulianDate JJ=*this;
- JJ.J-=Days;
- return JJ;
- }
-
- JulianDate JulianDate::operator++(int) // postfix operator
- {
- JulianDate OJ(*this);
- J++;
- return OJ;
- }
-
- JulianDate JulianDate::operator--(int) // postfix operator
- {
- JulianDate OJ(*this);
- J--;
- return OJ;
- }
-
-
- //.parse
-
- Date Today()
- {
- Registers R;
- R.AH()=0x2a;
- CallBIOS(33,R);
- Date D(R.CX(),R.DH(),R.DL());
- return D;
- }
-
- /*
-
- Moment class. Remember that there are 1440 minutes in a day.
- No consideration is taken for GMT or daylight savings time. If you
- need that sort of stuff, you can inherit this class and do your own
- tweaking.
-
- */
-
- //.parse
-
- Moment::Moment(const JulianDate& J, int Hour, int Minute)
- {
- M=J.J*MinutesInADay+Hour*60+Minute;
- }
-
- //.parse
-
- Time CurTime()
- {
- struct time t;
- gettime(&t);
- Time T(t.ti_hour,t.ti_min,t.ti_sec);
- return T;
- }
-
- //.parse
-
- int CurMinCount()
- {
- struct time t;
- gettime(&t);
- int X=t.ti_min+t.ti_hour*60;
- return X;
- }
-
- //.parse
-
- Moment CurMoment()
- {
- date d;
- getdate(&d);
- Moment M(JulianDate(d.da_year,d.da_mon,d.da_day));
- M+=CurMinCount();
- return M;
- }
-
- //.parse
-
- String40 Time::ShortDesc()
- {
- String40 S;
- if ((H==0)&&(M==0)) S="midnight";
- else if ((H==12)&&(M==0)) S="noon";
- else
- {
- int Hour=H;
- Bool AM=(H<12);
- if (!AM) Hour-=12;
- if (Hour==0) Hour=12;
- S+=Str(Hour)+':'+Form("@@",M)+(AM?"am":"pm");
- }
- return S;
- }
-
- //.parse
-
- String40 Time::Desc()
- {
- String40 St;
- if ((H==0)&&(M==0)) St="midnight";
- else if ((H==12)&&(M==0)) St="noon";
- else
- {
- int Hour=H;
- Bool AM=(H<12);
- if (!AM) Hour-=12;
- if (Hour==0) Hour=12;
- St+=Str(Hour)+':'+Form("@@",M)+':'+Form("@@",S)+(AM?"am":"pm");
- }
- return St;
- }
-
- //.parse
-
- Time::Time(const Moment& MM)
- {
- int X=int(MM%MinutesInADay);
- S=0;
- M=X%60;
- H=X/60;
- }
-
- //.parse
-
- String40 Moment::RelativeDesc()
- {
- JulianDate J=*this;
- Date D(J);
- String40 S=D.RelativePastStr()+' ';
- Time T(*this);
- S+=T.ShortDesc();
- return S;
- }
-
- //.parse
-
- String40 Moment::FullDesc()
- {
- JulianDate J=*this;
- Date D(J);
- String40 S=D.FullDesc()+' ';
- Time T(*this);
- S+=T.ShortDesc();
- return S;
- }
-
- //.parse
-
- String40 Moment::ShortDesc()
- {
- JulianDate J=*this;
- Date D(J);
- String40 S=D.ShortDesc()+' ';
- Time T(*this);
- S+=T.ShortDesc();
- return S;
- }
-
- //.parse
-
- Moment Moment::operator-(long X)
- {
- Moment MM=M;
- MM.M-=X;
- return MM;
- }
-
- //.parse
-
- Moment Moment::operator+(long X)
- {
- Moment MM=M;
- MM.M+=X;
- return MM;
- }
-